import GameServer from "../gameServer";
import Room from "../room/room";
import PongAI from "./bot/pongAI";
import GameLoop from "./gameLoop";

export default class Game {
  room: Room;
  ai: PongAI[] = [];
  server: GameServer;
  gameLoop: GameLoop;
  state = GameState.Ready;

  constructor(room: Room, server: GameServer) {
    this.room = room;
    this.server = server;
    room.game = this;
    this.gameLoop = new GameLoop(this, this.server.mainLoop);
  }

  start() {
    if (this.room.players.some((player) => !player.isReadyRecvFrame)) {
      this.room.broadcastMsg({
        type: 'start',
        data: { fps: this.gameLoop.fps }
      });
      return;
    }
    this.room.players.forEach((player) => {
      player.lastSn = 0;
    });
    this.server.mainLoop.add(this.gameLoop);
    this.gameLoop.isPause = false;
    this.state = GameState.Playing;

    this.room.players
      .filter((p) => p.isBot())
      .forEach((p) => {
        this.ai.push(new PongAI(p, this.gameLoop));
      });
  }

  pause() {
    if (this.state != GameState.Playing) {
      return;
    }
    this.state = GameState.Paused;
    this.gameLoop.isPause = true;
    this.room.broadcastMsg({ type: 'pause' });
  }

  resume() {
    if (this.state != GameState.Paused) {
      return;
    }
    this.state = GameState.Playing;
    this.gameLoop.isPause = false;
    this.room.broadcastMsg({ type: 'resume' });
  }

  free(server: GameServer) {
    server.mainLoop.remove(this.gameLoop);
    server.roomManager.delete(this.room, server.playerManager);
    server.gameManager.delete(this);
  }
}

export enum GameState {
  Ready,
  Playing,
  Paused,
}

export class GameManager {
  private games = new Set();

  create(room: Room, server: GameServer) {
    const game = new Game(room, server);
    this.games.add(game);
    return game;
  }

  delete(game: Game) {
    this.games.delete(game);
  }
}